\subsubsection{x64: 8 arguments}

\myindex{x86-64}
\label{example_printf8_x64}
To see how other arguments are passed via the stack, let's change our example again 
by increasing the number of arguments to 9 (\printf format string + 8 \Tint variables):

\lstinputlisting[style=customc]{patterns/03_printf/2.c}

\myparagraph{MSVC}

As it was mentioned earlier, the first 4 arguments has to be passed through the \RCX, \RDX, \Reg{8}, \Reg{9} registers in Win64, while all the rest---via the stack.
That is exactly what we see here.
However, the \MOV instruction, instead of \PUSH, is used for preparing the stack, so the values are stored to the stack in a straightforward manner.

\lstinputlisting[caption=MSVC 2012 x64,style=customasmx86]{patterns/03_printf/x86/2_MSVC_x64_EN.asm}

The observant reader may ask why are 8 bytes allocated for \Tint values, when 4 is enough?
Yes, one has to recall: 8 bytes are allocated for any data type shorter than 64 bits.
This is established for the convenience's sake: it makes it easy to calculate the address of arbitrary argument.
Besides, they are all located at aligned memory addresses.
It is the same in the 32-bit environments: 4 bytes are reserved for all data types.

% also for local variables?

\myparagraph{GCC}

The picture is similar for x86-64 *NIX OS-es, except that the first 6 arguments are passed through the \RDI, \RSI,
\RDX, \RCX, \Reg{8}, \Reg{9} registers.
All the rest---via the stack.
GCC generates the code storing the string pointer into \EDI instead of \RDI{}---we noted that previously: 
\myref{hw_EDI_instead_of_RDI}.

We also noted earlier that the \EAX register has been cleared before a \printf call: \myref{SysVABI_input_EAX}.

\lstinputlisting[caption=\Optimizing GCC 4.4.6 x64,style=customasmx86]{patterns/03_printf/x86/2_GCC_x64_EN.s}

\myparagraph{GCC + GDB}
\myindex{GDB}

Let's try this example in \ac{GDB}.

\begin{lstlisting}
$ gcc -g 2.c -o 2
\end{lstlisting}

\begin{lstlisting}
$ gdb 2
GNU gdb (GDB) 7.6.1-ubuntu
...
Reading symbols from /home/dennis/polygon/2...done.
\end{lstlisting}

\begin{lstlisting}[caption=let's set the breakpoint to \printf{,} and run]
(gdb) b printf
Breakpoint 1 at 0x400410
(gdb) run
Starting program: /home/dennis/polygon/2 

Breakpoint 1, __printf (format=0x400628 "a=%d; b=%d; c=%d; d=%d; e=%d; f=%d; g=%d; h=%d\n") at printf.c:29
29	printf.c: No such file or directory.
\end{lstlisting}

Registers \RSI/\RDX/\RCX/\Reg{8}/\Reg{9} have the expected values.
\RIP has the address of the very first instruction of the \printf function.

\begin{lstlisting}
(gdb) info registers
rax            0x0	0
rbx            0x0	0
rcx            0x3	3
rdx            0x2	2
rsi            0x1	1
rdi            0x400628	4195880
rbp            0x7fffffffdf60	0x7fffffffdf60
rsp            0x7fffffffdf38	0x7fffffffdf38
r8             0x4	4
r9             0x5	5
r10            0x7fffffffdce0	140737488346336
r11            0x7ffff7a65f60	140737348263776
r12            0x400440	4195392
r13            0x7fffffffe040	140737488347200
r14            0x0	0
r15            0x0	0
rip            0x7ffff7a65f60	0x7ffff7a65f60 <__printf>
...
\end{lstlisting}

\begin{lstlisting}[caption=let's inspect the format string]
(gdb) x/s $rdi
0x400628:	"a=%d; b=%d; c=%d; d=%d; e=%d; f=%d; g=%d; h=%d\n"
\end{lstlisting}

Let's dump the stack with the x/g command this time---\IT{g} stands for \IT{giant words}, i.e., 64-bit words.

\begin{lstlisting}
(gdb) x/10g $rsp
0x7fffffffdf38:	0x0000000000400576	0x0000000000000006
0x7fffffffdf48:	0x0000000000000007	0x00007fff00000008
0x7fffffffdf58:	0x0000000000000000	0x0000000000000000
0x7fffffffdf68:	0x00007ffff7a33de5	0x0000000000000000
0x7fffffffdf78:	0x00007fffffffe048	0x0000000100000000
\end{lstlisting}

The very first stack element, just like in the previous case, is the \ac{RA}.
3 values are also passed through the stack: 6, 7, 8.
We also see that 8 is passed with the high 32-bits not cleared: \GTT{0x00007fff00000008}.
That's OK, because the values are of \Tint type, which is 32-bit.
So, the high register or stack element part may contain \q{random garbage}.

If you take a look at where the control will return after the \printf execution,
\ac{GDB} will show the entire \main function:

\begin{lstlisting}[style=customasmx86]
(gdb) set disassembly-flavor intel
(gdb) disas 0x0000000000400576
Dump of assembler code for function main:
   0x000000000040052d <+0>:	push   rbp
   0x000000000040052e <+1>:	mov    rbp,rsp
   0x0000000000400531 <+4>:	sub    rsp,0x20
   0x0000000000400535 <+8>:	mov    DWORD PTR [rsp+0x10],0x8
   0x000000000040053d <+16>:	mov    DWORD PTR [rsp+0x8],0x7
   0x0000000000400545 <+24>:	mov    DWORD PTR [rsp],0x6
   0x000000000040054c <+31>:	mov    r9d,0x5
   0x0000000000400552 <+37>:	mov    r8d,0x4
   0x0000000000400558 <+43>:	mov    ecx,0x3
   0x000000000040055d <+48>:	mov    edx,0x2
   0x0000000000400562 <+53>:	mov    esi,0x1
   0x0000000000400567 <+58>:	mov    edi,0x400628
   0x000000000040056c <+63>:	mov    eax,0x0
   0x0000000000400571 <+68>:	call   0x400410 <printf@plt>
   0x0000000000400576 <+73>:	mov    eax,0x0
   0x000000000040057b <+78>:	leave  
   0x000000000040057c <+79>:	ret    
End of assembler dump.
\end{lstlisting}

Let's finish executing \printf, execute the instruction
zeroing \EAX, and note that the \EAX register has a value of exactly zero.
\RIP now points to the \INS{LEAVE} instruction, i.e., the penultimate one in the \main function.

\begin{lstlisting}
(gdb) finish
Run till exit from #0  __printf (format=0x400628 "a=%d; b=%d; c=%d; d=%d; e=%d; f=%d; g=%d; h=%d\n") at printf.c:29
a=1; b=2; c=3; d=4; e=5; f=6; g=7; h=8
main () at 2.c:6
6		return 0;
Value returned is $1 = 39
(gdb) next
7	};
(gdb) info registers
rax            0x0	0
rbx            0x0	0
rcx            0x26	38
rdx            0x7ffff7dd59f0	140737351866864
rsi            0x7fffffd9	2147483609
rdi            0x0	0
rbp            0x7fffffffdf60	0x7fffffffdf60
rsp            0x7fffffffdf40	0x7fffffffdf40
r8             0x7ffff7dd26a0	140737351853728
r9             0x7ffff7a60134	140737348239668
r10            0x7fffffffd5b0	140737488344496
r11            0x7ffff7a95900	140737348458752
r12            0x400440	4195392
r13            0x7fffffffe040	140737488347200
r14            0x0	0
r15            0x0	0
rip            0x40057b	0x40057b <main+78>
...
\end{lstlisting}
